{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "c5972a5b-3987-4666-af0e-13fd17f69d20",
   "metadata": {},
   "source": [
    "### 图像加载与预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "db1002d7-5504-42ed-8078-34d8ffa1f9bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "01f8efbf-fcd7-4dee-8c97-f8f059c6302a",
   "metadata": {},
   "source": [
    "### 加载图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7311f496-51b2-418e-a3f5-54f82639168d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x500 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "image = cv2.imread('./data/5678.png', cv2.IMREAD_GRAYSCALE) # cv2.IMREAD_GRAYSCALE表示加载为灰度图像\n",
    "\n",
    "# 二值化\n",
    "\"\"\"\n",
    "黑色（0） 白色（255）\n",
    "127是阈值\n",
    "255是大于阈值时设置的像素值\n",
    "cv2.THRESH_BINARY_INV是指反转二值化（黑色为前景，白色为背景）\n",
    "如果用cv2.THRESH_BINARY，则会得到常规的白底黑字二值图像\n",
    "\"\"\"\n",
    "_, binary_image = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)\n",
    "\n",
    "plt.figure(figsize=(10, 5))\n",
    "# 显示原始图像\n",
    "plt.subplot(1, 2, 1)  # 1行2列，第1个子图\n",
    "plt.imshow(image, cmap='gray')\n",
    "plt.title(\"Original Image\")\n",
    "plt.axis('off')\n",
    "\n",
    "# 显示二值化后的图像\n",
    "plt.subplot(1, 2, 2)  # 1行2列，第2个子图\n",
    "plt.imshow(binary_image, cmap='gray')\n",
    "plt.title(\"Binary Image\")\n",
    "plt.axis('off')\n",
    "\n",
    "# 展示图像\n",
    "plt.tight_layout()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3528fac4-27cf-4cdb-a0a2-c1c05893c45d",
   "metadata": {},
   "source": [
    "### 轮廓检测"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "607e2ada-b7f0-435f-8c7c-979339491703",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "cv2.RETR_EXTERNAL：表示只检测外部轮廓，不考虑内部轮廓\n",
    "cv2.CHAIN_APPROX_SIMPLE：使用简单的链式近似法来表示轮廓。它将多余的点压缩成直线段，只保留轮廓的端点，从而减少计算量。\n",
    "\"\"\"\n",
    "contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n",
    "# 按轮廓的中心点的 x 坐标排序\n",
    "def sort_contours(contours):\n",
    "    # 将轮廓转换为列表\n",
    "    contours_list = list(contours)\n",
    "    # 按 x 坐标排序\n",
    "    contours_list.sort(key=lambda c: cv2.boundingRect(c)[0])\n",
    "    return contours_list\n",
    "\n",
    "# 对轮廓进行排序\n",
    "contours = sort_contours(contours)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c7a1225f-3ff1-48d7-8dae-7565a151d53e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 遍历轮廓，提取每个数字\n",
    "digit_images = []\n",
    "for contour in contours:\n",
    "    x, y, w, h = cv2.boundingRect(contour) # cv2.boundingRect(contour)：这个函数返回一个最小矩形（bounding box），它包围了每个轮廓\n",
    "    if h > 20 and w > 10:  # 筛选掉过小的区域\n",
    "        # digit = binary_image[y:y+h, x:x+w]\n",
    "        padding = 30  # 增加边缘填充\n",
    "        digit = binary_image[max(y - padding, 0):y + h + padding, max(x - padding, 0):x + w + padding]\n",
    "        # digit_resized = cv2.resize(digit, (28, 28))  # 调整到模型输入大小\n",
    "        digit_images.append(digit)\n",
    "len(digit_images)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f650dda1-761d-441e-b9ad-42ebfc7f088c",
   "metadata": {},
   "source": [
    "### 展示分割之后的图像"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "148035ac-26a1-42ad-83c4-91b8c5464a57",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\PC\\AppData\\Local\\Temp\\ipykernel_14912\\873330583.py:4: UserWarning: The figure layout has changed to tight\n",
      "  plt.tight_layout()\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 4 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure()\n",
    "for i in range(len(digit_images)):\n",
    "    plt.subplot(1, len(digit_images), i + 1)\n",
    "    plt.tight_layout()\n",
    "    plt.imshow(digit_images[i], cmap='gray', interpolation='none')\n",
    "    plt.xticks([])\n",
    "    plt.yticks([])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "760a2cff-982b-451e-a38d-06b864be2a72",
   "metadata": {},
   "source": [
    "### 数字识别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "15a8d010-e869-4b0a-98e6-34470b778de4",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "from PIL import Image\n",
    "import torchvision.transforms as transforms"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a1810aa4-c3a7-4f8f-89d3-73602bfc1f5d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "device(type='cuda')"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "2c04f841-f5b6-4e9f-9811-34233af616d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "class Net(torch.nn.Module):\n",
    "    def __init__(self):\n",
    "        # （batch,1,28,28）\n",
    "        super(Net, self).__init__()\n",
    "        self.conv1 = torch.nn.Sequential(\n",
    "            torch.nn.Conv2d(1, 32, kernel_size=3), #（batch,32,26,26） 输入通道数1输出通道数32 32为小型任务的经验性选择，一般每层增加一倍欠拟合就加过拟合减\n",
    "            torch.nn.BatchNorm2d(32), # 对卷积层的输出进行批量归一化，使得每个特征图的分布更加稳定，从而加速训练并提高模型性能。\n",
    "            torch.nn.ReLU(),\n",
    "            torch.nn.MaxPool2d(kernel_size=2), #（batch,32,13,13）\n",
    "        )\n",
    "        self.conv2 = torch.nn.Sequential(\n",
    "            torch.nn.Conv2d(32, 64, kernel_size=3), #（batch,64,11,11）\n",
    "            torch.nn.BatchNorm2d(64),\n",
    "            torch.nn.ReLU(),\n",
    "            torch.nn.MaxPool2d(kernel_size=2), #（batch,64,5,5）\n",
    "        )\n",
    "        self.fc = torch.nn.Sequential(\n",
    "            torch.nn.Linear(1600, 50), # 1600 == 64*5*5\n",
    "            torch.nn.ReLU(),  # 添加ReLU激活函数 增加模型的非线性能力\n",
    "            torch.nn.Dropout(0.5), # 有效防止过拟合-丢弃率0.5          BN层和dropout层一起用效果不好（ 深层可能不好BN在后Dropout在前也不好\n",
    "            torch.nn.Linear(50, 10)\n",
    "        )\n",
    "\n",
    "    def forward(self, x):\n",
    "        batch_size = x.size(0)\n",
    "        x = self.conv1(x)  # 一层卷积层,一层池化层,一层激活层\n",
    "        x = self.conv2(x)  # 再来一次\n",
    "        x = x.view(batch_size, -1)  # flatten 变成全连接网络需要的输入\n",
    "        x = self.fc(x)\n",
    "        return x  # 最后输出的是维度为10的，也就是（对应数学符号的0~9）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d8f1b186-9175-4b86-9007-241feaaaf59b",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\PC\\AppData\\Local\\Temp\\ipykernel_14912\\457276358.py:6: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n",
      "  model.load_state_dict(torch.load(model_path))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Net(\n",
       "  (conv1): Sequential(\n",
       "    (0): Conv2d(1, 32, kernel_size=(3, 3), stride=(1, 1))\n",
       "    (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "  )\n",
       "  (conv2): Sequential(\n",
       "    (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1))\n",
       "    (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
       "    (2): ReLU()\n",
       "    (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
       "  )\n",
       "  (fc): Sequential(\n",
       "    (0): Linear(in_features=1600, out_features=50, bias=True)\n",
       "    (1): ReLU()\n",
       "    (2): Dropout(p=0.5, inplace=False)\n",
       "    (3): Linear(in_features=50, out_features=10, bias=True)\n",
       "  )\n",
       ")"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model = Net().to(device)\n",
    "\n",
    "model_path = '../models/1_Handwritten_Digit_Recognition/model_weights.pth'\n",
    "\n",
    "# 加载模型参数\n",
    "model.load_state_dict(torch.load(model_path))\n",
    "\n",
    "# 将模型设置为评估模式\n",
    "model.eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "8de5b620-69ce-4673-9f1c-18ee851dd87f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 预测函数\n",
    "def predict_image(image, model):\n",
    "    # image = Image.open(image_path)\n",
    "    image = Image.fromarray(image)\n",
    "    # 图像预处理\n",
    "    transform = transforms.Compose([\n",
    "        transforms.Grayscale(num_output_channels=1),  # 转换为灰度\n",
    "        transforms.Resize((28, 28)),                 # 调整到 28x28\n",
    "        transforms.ToTensor(),                       # 转换为张量\n",
    "        transforms.Normalize((0.1307,), (0.3081,))         # 归一化到 [-1, 1]\n",
    "    ])\n",
    "    image = transform(image)\n",
    "    image = image.to(device)\n",
    "    image = image.unsqueeze(0)\n",
    "    \n",
    "    with torch.no_grad():\n",
    "        output = model(image)\n",
    "        _, predicted = torch.max(output.data, 1)\n",
    "    return str(predicted.item())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "1724057e-0d25-482f-8e4e-015bb1e84894",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAEwCAYAAAAq3XLJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAuFElEQVR4nO3deXRT95028OdqsSTb8ibv+wYYcIAmECiFE5awBAg5JEMKDSUnzRlSmjNTmmmak55Op2mZYTozDG2alExCmmkyYThNKUwISSAEwmZWs8RgYuN9l42NF8mWbUn3/YOxJn4tyTZIurq6z+cc/+GrK+lrWcuj3yqIoiiCiIiIFEsldQFEREQkLYYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4hgEiIiKFYxggIiJSOIYBIiIihWMYICIiUjiGASIiIoVjGCAiIlI4jdQFEBGRtPr7+9Hf3y91GVCpVAgPD4dKxe+pgcYwQESkcEePHsXBgwelLgMpKSnYsmULIiIipC5FcRgGiIgUwuFwoKWlBQMDA8OO19bWoq6uTqKq/s/g4CCqq6tHhIGEhARERkZKVJUyCKIoilIXQURE/tfT04Nf/epXaGhoGHZ8YGBgRECQgkqlgsFggCAIw45v3rwZ8+fPl6gqZWDLABFRiBNFEWVlZWhqasKtW7dgsVikLsktp9MJq9U64viNGzeg0bj/uEpOTkZOTo6/Swt5bBkgIgpxDocDv/71r3Hu3DnI8S3//28p+LpVq1bhr//6rwNYTWjikE0iohBWUlKCvXv3oqGhQZZBALjTsuHpp7y8HB988AEqKyulLlPW2E1ARBTCLl26hL1790pdht+UlZWhrKwMkZGRyMvLk7oc2WIYICKiEWJjY7F27VqEh4f75faLiopw/vx5v9w2jR/DABFRCHI4HBgYGIDdbh/1XLVaDa1WO+xYTEwM5s2bh5iYGL/UZzab8eWXXw475nQ673pWw+DgIGw2G7RaLdRqtS9KVBQOICQiCkHFxcXYs2cP2tra0NHR4fXcxYsXY9myZcOOhYWFITMz0+Mo/nvV1taG9vb2YcdaWlrwxhtvoLe3d9y3l5SUhPj4eDz77LPIz8/3VZmKwZYBIqIQ1NXVhbKyMreXaTQaxMXFuUbpZ2dno6CgIJDlISEhAQkJCcOOGY1GpKSkeJ366HA40NHRAafTOey42WxGR0fHXQUJYhggIlKclJQUvPTSS66V/gwGg8QV3ZGUlIS///u/9zrrwWw2Y9u2bejq6gpgZaGPYYCISGHUajViY2NhNBqlLmWYoRYLb/r7+7mRkR/wESUiIlI4hgEiohDS2dmJw4cPjxipHyoiIiKwaNEizJo1a8TKhE6nE+fPn8exY8c4dmCc2E1ARBRCzGYzdu3aBZvNJnUpfhEdHY2NGzfiypUruHz58rCpkw6HAx9++CFMJhOmTJnitzUSQpHiwkBFRQWOHTvm+v3hhx/mJhdEJHu9vb348MMPUVdXh8HBQbfn6HQ6rFq1CtnZ2dDpdAGu0He87VVAd0cxYUAURTgcDtTX1+PAgQMA7jyhCgoKkJGRAbVazScYEcmOKIqu3f6OHj2KlpYWt+cNbQ+8YMECZGVlBbhKCnaKCQPNzc344x//iObmZtcxURTx5z//GadPn8bTTz+NlJQUCSskIho/p9OJ999/H2VlZR4XFxIEAU8++SSmTp2KxMTEAFdIchDyYcDpdMJiscBsNuPKlSvo6+sbdnl1dTVaW1tHHCcikgOn04mKigqUlJS4vVyv1yM8PBwFBQWYPn16gKsjuQj5MGCxWLB9+3Y0NDSE7IAaIiJPli9fjmXLlo06f5+ULeTDgNPphNlsRltbm9dz6uvrRyxvKYW4uDi+aP2ktbUV3d3dAO4supKenj5icxYiORla39/bNLqoqCikpaUFsCqSo5APA2PR19eH119/PSgGEP7VX/0V1q5dK3UZIUcURXz44Yf47LPPAAAmkwm/+MUv2H9KsvbRRx/h008/RX9/v9SlkMwxDPyvYOlCqKiowIkTJ1BQUMAPKh9pbGxERUUFamtrXWNDOjs7ce7cOWRkZOC+++7jlqckK01NTbh58yZqamo8jndKTEzEpEmTkJGREeDqSI4YBoLMmTNncO7cOfzd3/0dw4CPXL58GW+++eawYxaLBW+99RamTJmCyZMnMwyQrFy9ehU7d+70es6UKVOwZcuWoGjxpOAXsmHA6XTi+PHjqK6uRk9Pj9TljIsoil537SLfCbXHWRRFFBUVoaamBsCd/uIlS5ZAr9dLWxgFnCAIrh+i0YRkGBhaYOj48eO4dOmS1OUQBcTQ4jNFRUU4efIkACAtLQ3z5s1zrTbHDwaSu7F8WeLzfPxCMgwcO3YM58+fR3V1tdSlEAVMUVERTp06hbKyMtexjo4OvP766ygoKMCaNWvYHUKy19nZid27d6OhoQEOh2PYZWq1GmvXrkV+fj6io6MlqlCeQjIMVFdXo6ioaFzX0ev1QbNHtiAI0GhC8l9DflRfX4/Tp08PO9bX14fz589jYGAAS5cu9RoG1Go1dDodv1XJnEqlgl6vR1hYmNSl+MXQc/r27dsjLlOpVCgsLMS0adMkqEze+IkDwGAw4Pnnn0dqaqrUpQC4EwY4eJB8qby8HD//+c+9ftDn5eXhueee49oLMpeRkYHNmzfDZDJJXQrJCMMA7qTJ9PR05ObmSl0KkV/09vaiqqrK6zkqlQoNDQ2uMBATE4PIyMhAlEc+pNPpkJOTA4PBIHUpJCMMA0QEAKiqqsLPf/5z1+8bNmzAsmXLJKyIiAJFcWEgNjYWOTk5w44ZDAaEh4dLVBH5S3d3NyoqKlBXVyd1KQGRkpKC+++/H9XV1W77U0fjcDjQ1dXl+r2yshLFxcUAAI1Gg0mTJnGKIknG4XDg5s2bqK+vx+DgoNTlhBzFhYGpU6fiRz/60Yi+U46yDj1VVVXYtm2bYt445s+fj7lz52LHjh04derUPd/eoUOHXMs3x8bG4h//8R+5zTdJZmBgAO+88w7Ky8tHzCKgexdSYaC2thZXrlxBZWWlx3NUKhU0Gg1HTIcwi8WC06dPo7KyEoODg243oNLr9Zg3bx5ycnJCJgiqVCoIgoCZM2e6Nrvq6enB6dOnMTAwMO7bG1qvAwCsViuOHDmCqKioUa8XFRWFb33rWyE7mp0CSxRFXL58GdXV1bh16xaDgJ+EVBgoKyvD22+/LXUZJCFRFNHd3Y3du3d7bSqPiIjAt7/9bSQlJQWwOv8TBAGLFi3CokWLAAANDQ24dOnSXYWBr+vr68MHH3wwpnOzsrIwc+ZMyWYlMOiHjqHFhY4fP45jx45JXE1oC6kw4E1CQgIee+wxZGVlSV0K+cnAwAA+/PBDVFdXe9zSVa1WY9WqVcjLyxvTt1y5i4mJwTPPPOM1DPT09GDfvn2wWCw+uc/29na8/fbbkoSBCRMmYMmSJQwEIeLSpUs4e/bssIW0yD8UEwaioqLw8MMPc6BgCBpqzrbZbDhz5gxu3rzp9ryhRXVmz56NwsLCAFcpjcjISFcrgSdtbW04cuTIiG1wHQ6H2y6W0VgsFhw9enTc1/MFq9WKhx56CBqNJmS6f5SsqqoKhw4dcnuZu8XZtFpt0CweJzeKCQMU2vbt24fi4mI0NDR4PGflypWYM2cOsrOzA1eYDERHR2PLli0jBloePHgQZ86ckaiqu1NSUoJXXnkFS5YswcKFC6Uuh/woNzcXGzduHBb6VCoVX993iWGAZK23txdWqxWVlZUoLS11e45er0dERATy8vIU0yIwHmFhYZg8efKI49euXUN5eTmAO7uAdnV13VVLQSB1dXWhq6sL06dPl7oUugf9/f3o6enx2N0HAEajEYWFhVwx00cYBkjWvvjiC/zlL39Bd3e3x3Pmzp2LdevWKWKMgC+tWrXK1cXQ3d2Nf/mXf0Fra6vEVZESlJaWYufOnT4bx0KjYxggWbNarR4/oMLDw5GRkYGcnBwkJycHuDL5i4qKcgWo8PBwTJw40TVl0R2Hw4G6uroRYw+Ixspms6Gurg6VlZUwm81utyrWarXIyspCRkYGB4r6EMMAhay8vDy8/PLL0Ol0Upcie0ajET/84Q+97iNvsVjwi1/8QjErPpLvtba24p//+Z/R1dXl8blmMpnw4osvwmQycZCoD4VEGOjs7MSVK1fw1VdfSV0KBUhbWxtKSkq8LjA1NHuAfYr3ThCEMYWqOXPmID8/3+/1iKKIq1evoqOjw+/3RYEjiiL6+/vdrhqqVqsxY8YMZGVlISoqiota+VhIhIHGxka89tpr97ywCslHZWUlXn311aAf0KYkOp0OTz31VEDuy+FwYOvWrQwDCqLVarFu3TpMnDhR6lJCUkiEAW/0ej2WL1+OrKwsfkOUsf7+fhw6dMi1qmBTU5PHZkSj0ej6n7MZMXDYf0uBwOeZf4R8GNDpdFi2bBnS0tKkLoXugiiKEEURNpsNR44cQU1NzajXiYyMxMqVK70OdiMi6Q29voeCPVv6pBPyYYDkTRRF7Nu3D9evX+e0NqIQM/T6Hhrv1dfXh76+PomrUiZZhwGn04ne3l709fW5bTI2GAyIjIzk8pQyV1ZWhosXL47pXIPBgIiICDYlEgWpwcFB2Gw2AHfew69fvz7m1zf5j6zDQFdXF37zm9+gubkZdrt92GUqlQpPP/007rvvPsTHx0tUIQWSTqfD5s2bkZ+fD6PRKHU5ROTG1atX8e6777q+wLW1tUlcEQEyDwN2ux0NDQ1un0yCICApKQkZGRkSVEaBEhUVhZiYGAB3wkB2djbS09OlLYr8qqOjA52dna5vl18XHh6O+Ph4REdHS1AZedPf3w+z2Yyampoxjf35OpPJhLi4OK4Z4keyDgNECxYswJNPPgngTgDkrpSh7+OPP8bHH3/stm95+vTp+MEPfgC9Xi9BZeRNQ0MDtm3b5nXpcE/Wrl2L+fPn8/XtRwwDJGthYWHcc0AhWltbUV1djZqaGo9r1mu1WkRFRXHMSBByOp3o6elx26LjSWpqKjIyMpCens6uPz9jGCAiWbh69Spef/11r0siU2j55je/iQ0bNnAQeAAwDFDQun79Om7cuIGmpiapS6EgIIqix3noMTExmD9/PlenCyJOpxNFRUUwm80AgFu3bo0Y6O1JSkoK5syZg8LCQi4cFiCyDAP8ZqAMly5dwgcffCB1GSSxsbzeTSYTnnrqKfYpB8BY33+dTic+++wzXL58edz3kZWVhY0bNzIIBJAsw4DD4cD+/ftRWVmJnp4eqcshCeTm5mLlypXIycmRuhTys6amJuzfv5+7IQYBURRx9OhRXLt2bUzn1tbWjul2dTodnnjiCdc08ISEBHYNBJjswsDQghUXL15EaWmp1OWQRBISErBo0SJ+cwhhoihiYGAAbW1tOHbsmMeNyMLCwriD3dcMPW7+GkR57do1fP755z69Ta1Wi9mzZzPcS0hWYUAURRw4cABnzpxBfX291OUQkR91dXVh586daGpqcrulLQBERERg8+bNSE9P5xz0/1VfX4+tW7f67Zt1c3OzX26XpCWrMADceSKWlZVJXQYR+Ykoiujs7ITZbEZZWZnHbYqjo6MRHx+PiRMnIjk5OcBVBi+bzcb3SBo32YUBIgptg4ODePPNN1FaWoquri6356hUKjzzzDOYPn06Vxsk8oGQDQOiKKKmpkY2fYnR0dHIyMjgYilEuNNFcPv2bbeXJScnIzExEWlpaTCZTAGujMZLo9EgJyfHazeOwWDgqpESC9kw4HQ68f7778vmw/Vb3/oWtmzZIpt6iaSybNkyPProo9BoQvbtK6RERETgb/7mb5Camur1PP4/pRXSj/5YF7gIBg0NDTh8+DDy8/ORn58vdTmSampqQklJCaqqqqQuhYKQWq2WTYufr/T29uLChQuupXylnkmlUqnwwAMPIDY2dtRzw8PDERMTo7j/mdyEdBiQk4qKClRUVGD9+vWKDwPl5eV4/fXXpS6DKGh0d3fjP//zP9He3i51KQDufItfs2YNpk6dKnUp5CMMA0Hm0qVLsFqtWLhwIfLy8qQuJ6Da2trw8ccfo7q62uM5sbGxWLlyJbKzs7koCYW8wcFBfPrpp6iqqoLVah3TdRISErBixQq/Nrur1WqkpKSwWzOEMAwEmbKyMpSXlyM/Px9ZWVlQq9Uh/4ITRREOhwPt7e0et6YdYjQasXz5cu5USIrgcDhw6tQp3LhxY8zXiY2NxYoVK2AwGPxYGYUahoEgJIoi9u3bh7Nnz2Ljxo2jDryRO6vVinfeeQf19fXo7++XuhwiIsWRXRgwGAyyn1dstVpHHdxYXV2NlpYWLF++HJGRkYiMjAy5ZnFRFGG1WtHe3o4vv/zStbuZO4IgICIiAkajMeRbSpRKFEX09fXBYrG4fX2EhYXBYDAoYqXBoceip6dHVgOhSb5kFwbWrFmDpUuXSl3GXXM6nXjjjTfGtNGHzWbDa6+9hoyMDLzwwgswGo0BqDBwnE4n3nnnHVy7dm3UgVEGgwF/+7d/i5ycHO5MF8L279+PEydO4NatWyMumzlzJjZs2CD7LwNjtXfvXpw+fdrtY0Hka7IKA4IgIDY2dkzTWYKVw+FATk4OLBYLGhsbPa65Dtz5dtDa2oqwsDA4HI4AVhkYoiji1q1bo651npSUhISEBGRkZCApKSlA1ZEUbt++jaamJreXRUREIC0tLeRahgYGBtDY2DjiNV5bW+vxsSDyNVmFgVCgUqnw3e9+F7dv38Yrr7zCF/soBEHAd77zHcyePZsrlFFIamtrw7Zt29Dd3T3suKddGon8gWEgwARBgF6vR3R0NGbOnIm6ujqUlJSE5Dd/b6qqqlBfX4/Ozk6P52RlZSEzMxNpaWnsGghxTU1NqKysREtLy4jLoqKiMHXqVEyYMEGCynyrtrYWdXV1w451dHSgq6vL6ywaIn9jGJCIwWDA9773PVRVVeFnP/sZent7pS4poI4ePYoDBw5AFEWP58ybNw9r164NuWZhGqm4uBi7du1y+3xIT0/Hj370I+h0Otk/F4qKirBnz54Rx729DogCgWFAIoIgQBAExMXF4YknnkBlZSWKiorcntvd3Y39+/cjNzcX8+bNC5lZBZ7eALOysjBnzhxMnTo1ZP5W8k4URa8fiEOvF7mw2Ww4evToiKb/a9eu+f2Dv729HXv37kV+fj5mz54tq8eNpMMwILG4uDisXbsWJ0+exJkzZ9y+UXR3d+Mvf/kLZs6ciblz58rujXG8srKysH79egiC4Pc3zlB+HIPZeP6vwfY/GkvtNpsNH330ERoaGgJQ0XDt7e3405/+hAULFuDBBx90e06wPaYkPYYBGamqqsKOHTswa9YsLFiwQOpy/Oarr77C9u3b/fqGFRkZifXr1ytmmlqw6ezsxJ49e1xL7DY2No44x2g0Yt26dcjIyAiqHe0sFgv27NmDrq4uj+cMDg5Kvo9AaWnpiNeRXq/Ht7/9bSQkJEhYGQWj4HmFKZxGo4HBYMDAwIDHRUY6Ojpw8uRJmEymkA4Dra2taG1t9et9xMXF4ZFHHoFOpwuJvmi5EEUR/f396OjoQFFRkdcPVJ1Oh9mzZyMxMTGAFXo2VHtXVxfOnj2LtrY2v96fVqsdNQQNDg56fL9w9zqKjIzEkiVLYDQa+bynYRgGgkRhYSF+9atf4dChQzh8+LDU5YS87u5ubN++HRMmTMBzzz3H7VUDpL+/H2+88QYqKythsVikLmdc7HY73nnnHdy4cQO3b9/2+/2tWbMGs2fP9nrOvn37cOrUqTHfZm9vL373u98hOzsbP/jBDzhLh1wYBoKE0WiE0WhEWVkZUlJScPv2bdfe5eR7drsdNTU1MBgMHMkdQE6nE/X19aitrfV6nslkQlJSEtRqdYAqG50oimhsbERNTY1Pb1ej0cBkMo34W3NyckadTpmZmYmUlBR0dHSMaV8Pp9OJuro6qFQqxU1nJu8YBoLM4sWLMXfuXOzcuRPnzp2TuhyigNNqtdi0aROmTJmCyMhIqcvxu4SEBPz0pz8dsRPnWL61r169GosXL8a///u/4/r16/4qkRSAYSDIDG3EEqrN1rdu3UJ9fb3fxwSQPGVkZCA5ORnJyckhMbjTYDAgPz/fawtHQkIC4uPjERERMe7bDw8Ph1arhVarHdf1+vr6UFJSguTkZOTk5HDsADEMUGBdvnwZO3fuZBMlubVixQosXbo0qLoH7kVycjJ+8pOfeP2WLwhCwP9es9mMf/3Xf8U3v/lN/PjHP2YYIIYBCoz29nacO3cO169f9zj6OTo6GnPmzPH5NLKamhqPTagdHR345JNPkJOTg2nTpvFNUWJqtXrc33IDoaSkBFVVVV53EJw8eTJyc3OHHYuPj4der/fr36RSqTB79mykpaUNO97Y2IgrV654vJ7D4UBjYyMOHjw47Hmv0WgwZ84cxMTE+KliCkYMA+Q3Xx+Y19zcjLffftvrLo0JCQl45plnfD7C+aOPPvIYBsxmM/7whz/g4YcfxrRp03x6vzScXAdqiqKIU6dO4ZNPPvF63uzZs/H4448HqKr/o1arsXLlyhHHjx496jUMAEB1dTXeeuutYccMBgPy8vIQHR3NcKwgDAPkF3a7HQcPHnTtytjR0eGxa8BgMOCxxx5DVlZWyI6VUDpRFHH06FHcuHEj5MaLTJo0CQsXLkRBQYHUpQwzceJEfP/738fZs2dHDQVfNzAwgL179yIrKwuPPfYYpx8qBMMA+ZzD4YDNZsOZM2dQWlrq9Vy1Wo2IiAgsWLAAqampAaqQpHD16lV88cUXbi9TqVSuH7lJT0/HI488EnTfotPT05Geno6Ojg5cu3YNDodjTK0zDocDRUVFqKmpwfLlyxkGFIJhgHxKFEUcOHAAFy5cGHUuuUqlwlNPPYXJkyfDZDIFqEIKRg8++CBWrFiBjIwMqUsJOYsXL8bUqVPx3//93/jqq6+kLoeCFMMA+VxDQwNKSkq8nhMeHo6IiAhMmjQJU6dO9Ws9Op0OcXFxsFqtY1qYhXyrr68Pvb29Xh/7hIQEzJgxI3BFKUhKSgqSkpJw4sQJVxeN3W5HT0+PbMdxkO8xDJAkVq1ahcWLFyMuLs7v9zV37lwUFhbi/fffx4kTJ/x+fzTcsWPHsH//fnR2dkpdimIJgoCNGzfiySefBHAnsG/fvh29vb0SV0bBgmGAAio6OhpJSUmuZVQDISIiAuHh4ez7DLCenh40NTWhpqYGLS0tbs8JDw9HWlpa0O6id/v2bbS2troNMnq93rVIUrATBAGxsbGu30VRxMSJE9Ha2uoa5Pv/GxwcRGVlJZKTk5GWlhZ0YyLItxgGKKBmzpyJTZs2BeVccvKt0tJS7NixAwMDAx7Pyc/Px0svvQS9Xh/Aysbu3Llz+MMf/uB2SmxmZiZ+9rOfyTJkJicn46c//SnOnj2LHTt2uO0uuHXrFn7961/j/vvvx4svvhhU20iT7/G/Sz5TX1+PiooKNDc3ezxHrVZDr9fzW4YCOJ1O9PX1uf2gMRgM+MY3voEJEyYgPDw86FYcvH37Nr788kvcuHHD44ZhKpUKer1eltNhx1L70JbNHGejDAwD5DOXL1/Grl27pC6DZCAmJgabNm0a1nQdTOrq6vDqq696XSSLKJQwDJDPeBuZnJiYiMWLF4+6JSspgyAIrp9g0tPTg8OHD6Ompob7Z5CiMAxQQCQkJOCJJ56QZZMqKYfFYsGBAwfQ0dHh9bxgDDJ3S6VSjRp8nE4nRFEMmb+ZRpLfcl9ERBKKjIzEc889hw0bNsh+IOykSZPw4osvYv78+R7Pqaqqwr/927/h888/D2BlFGhsGaB7ZrfbYbPZvI4aJ+UYWo7a08A7OdPr9YiNjcXMmTORmJgodTn3zGQyYe7cuWhpacGlS5fQ398/YlfRzs5OnD17NiT+XvKMYYDuWXl5OXbt2jVq0yopg9lsxu9+9zu0tbWF1Ap3Go0Gzz77LCZPnhy0Ax/v1sKFCzF9+nT813/9F4qLi6UuhyTAMED3rK+vD9XV1W77HdVqNRITE5GYmMj+xhDncDjQ2tqKuro6VFdXu13dThAEJCYmIiUlJag2JXI6nWhra0Nzc7Pb53FsbCxiYmKQnZ2NzMxMCSr0r6G/LzIyUupSSCIMA+RXMTExeOmll5CUlMRFS0JcX18fXn31VdTU1KCvr8/tOTqdDps3b8aECRMQERER4Ao9GxgYwM6dO1FeXg6r1Tri8tWrV2PJkiWyXGCIaCz47kx3zWaz4caNGygvL/fYHCwIAoxGY1C98ZN/iKIIi8Xi9sMUAHJycpCamoqkpCQYjcYAV+edKIqwWq2wWCxuLzcYDIiKigpwVcGlpaUFFy5cQHZ2dtAuH013j2GA7lp7ezt++9vforOzE06nU+pyKMitXr0aCxYsCKruARq7CxcuoLi4GJs3b8bSpUulLod8jGGA7onT6XQbBFQqFebOnYusrCwYDAYJKqNgo1Kpgm7ZYRo7URThcDhw6dIl2Gw2zJ07F/Hx8VKXRT7CMEDjNpYR4hqNBitWrEBhYWEAKiKiQCkqKsLFixeRm5vLMBBCGAZo3AYHB7Fv3z6PI8aJSJ6WLl2KgoIC7Nu3D62trVKXQwHEMBBk7HY77HZ7UK+Lbrfbce7cOVRUVLi9XKPRICwsjH3DRDIiCALuu+8+5OXl4eTJk7h9+zY3alIQhoEg88UXX+DIkSNoaGiQupS79uijj2LOnDkhOR+bKNTpdDps2rQJ9fX1+I//+A+PMywotDAMBAmbzYbu7m7U1NSgtLRU6nLuSWpqKiZPnix1GRQgoiiiu7sbHR0dI5ayBYDw8HBERkZCr9dLUB2Nl1qtRm5uLnQ6HdcGURD+p4NESUkJUzjJkiiKeO+991BcXIzOzs4Rly9cuBCPP/540K0tQET/h2EgSNhstqBfy10URTQ2NsJsNntcYY6UxWw2o7W1FQ0NDWhvb3d7Tnh4OBepIQpyDAM0Lnv37sXJkyc5sIgAAEeOHMG+ffv4fCCSOYYBGhe73e5xq+LMzExMmjQJaWlpAa6KpOJwODw+HxITEzFt2jTk5+cHuCoiGi+GAfKZGTNm4Nlnn5W6DAoSubm5eP755znFlEgGGAYk1t7ejk8++QTV1dUexwtER0djxYoVrtHYwfxNi9sUK0NFRQVOnDgx6swXQRD4nJCpqKgorF+/HhUVFThy5Miw9ye73Y6PP/4Y169fx8qVK7n1cQhgGJBYZ2cnDh486HGnN5VK5QoD0dHRAa6OaDhRFOF0OlFbW4v9+/d7PE+lUrFFQOaMRiMeeeQRFBcX4+jRo8MWQnM6nTh16hS++uorLFq0iGEgBDAMBDGdTofvfve7yMnJ4T7qFBSamprw3nvvobm52eM5iYmJ2LhxI1JTU9kqQCQTDAMScTqdsFqtsFqtbrsHDAYDoqOjcd999yEnJ0eCCon+z9Dz1Ww2o7i4GP39/SPOEQTBNY3w/vvv57dFIhlhGJCI1WrFjh07UF9f73bO/rp16zBr1iwkJiZKUB3RcD09PdixYwcaGxs9zh4wGAz44Q9/yG2riWRIlmHA6XSipaUFNpvN4zmCICApKSmomtfb29vR1dUFALBYLKivr4fZbB5xniAIMJlMSE9PD3SJIamrqwvt7e3o6emRuhTZcjqdaG5udvt8Be50DSQkJCAzMxMpKSkBro6I7pUsw4DdbseuXbtw48YNj+eo1Wr8+Mc/xowZMwJX2Cg+/fRTfPTRRwDuDMTiKn6BcebMGfzxj39027RN904QBGzYsAGzZs3i/gNEMiWrMCCKIqqqqtDQ0ACz2exxBD5wZzRzSUkJent7A1ihd9XV1V5rJv+w2+0eH3ej0YgpU6YE9XRNOdDr9YiIiJC6DCK6S7IKAwBw6NAhHDp0aNQ1/J1OJ/785z8HqKqxCeZ9B5QqLS0NL7zwAnQ6HUe+E5FiyS4MiKI45g9VOX74TpkyBYWFhcjMzJS6FNlraWnBqVOnvC6MIwgC58QTkeLJLgyEuunTp2P9+vVSlxESmpubsXv3btjtdqlLISIKagwDQWLixIlYsWIF1xQgIqKAk10Y0Gq1I0YsO51Oj3Ofg50gCNDpdEhLS8OCBQvYXO0DQ8+HgYEBWXYVBRNRFDEwMACbzeb2sdRoNAgLC+PzlkjmZBcGVq9ejYceemjYserqarz55puybA5OSUnB97//fSQmJnIAm490dHTg97//PVpaWoatp07j53Q68e677+L69etob28fcfmSJUuwaNEipKamSlAdEfmKrMKAIAhITk5GcnLysOMqlQqpqamybB1IT0/HxIkTg2pxJLlyOp3o6OhAY2Mjbt686VrgyR2VSgWTyQSTycQQ5oUoiqivr0dVVZXby+Pj4zFp0qQAVxV4XV1daGlpQWxsLHQ6ndTlEPmcrMKAJ9nZ2fjlL38pyyZhjUbDhVp8ZGBgAL///e9x8+ZNdHd3ez03OjoaP/nJT5CSkgKtVhugCkmu/ud//geff/45XnjhBUyZMkXqcoh8LiTCgFarRVxcnNRlKF5bWxuuXLki2f0PDAygpaXFa4uAIAjIzc1FamoqEhMTERUVFcAK5aWxsRFmsxkWi0XqUiTX29uL/v5+lJWVQRRF5Ofns4WAQkpIhAEKDufOncOFCxckrWG0MQIajQYbN25EYWEhNBo+/b359NNPcfDgQY67+F8OhwPvvvsu4uPjsXXrViQlJUldEpHP8N2QfMbpdMLpdEpdxghZWVmupl2NRoPExER2DXhRV1eHa9euoaqqSpaDcv3J4XDAYrHg2LFjyMzMxOzZs6FWq6Uui+ieMQxQyCssLMSmTZtcv3PAoHelpaV44403pC4jaFmtVuzevRsFBQW4//77GQYoJDAMUMhKS0vD8uXLkZeXxwBAXmm1Wjz22GOora3FgQMHgmqDM6JAYBigcVGpVCP62oOxe0CtViM5ORkrVqxglwCNSqPRYN68ecjLy8Nnn33GMECKwzBA47JmzRosWLBg2LGbN29i9+7dQRMI4uLi8L3vfQ+pqalswiUiGgOGARozQRCQnZ2N7OzsYcdVKhXi4uKCZrBZQkICpk2bhpiYGKlLCTlqtRpGo9H1e6itkaFSqRAdHe0Ktv39/ejr63N7rt1uR2dnJ4xGI8LDw9kVRbLGMED3bNKkSdi6dWvQLPqk0WiGfWCR72RkZGDLli2uOfahtk6DyWTCyy+/7JpOefz4cezZs8ftubW1tfiHf/gHzJ07Fxs3bgxkmUQ+xzBA90yv13NteoXQarVISUmBwWCQuhS/0Gg0w5Y7z8zMRH5+Ptra2kYsZjU4OIjm5mZ0dnYGuEoi3+NWY0REHsyZMwdbt27Fgw8+KHUpRH7FMEBE5IFGo4HBYPC6WmVLSwtOnDiB+vr6AFZG5FsMA0RE9+D69evYvn07Ll68KHUpRHeNYYCIyAeCZQAt0d3gAEIiAnDnw2zoh8ZPFMVha20IgsDphiQbDANEBACor6/HBx98gIaGBqlLkaXjx4+jsrISAGAwGPCd73wHJpNJ4qqIxoZhgIgAAF1dXSgqKsLg4KDUpQQdnU6H8PBw2Gw2jytt1tTUoKamBgBgNBqxbNkyhIeHQ6/Xs4WAgh7HDBAReSEIAh599FG88soryMvLG9N1rFYrfvOb3+C1116DzWbzc4VE944tA0REo0hISEBMTAwyMzNhsVjQ2trqWqXQHafT6epuqa+vdy3SFBUVhejo6IDUTDQeDANERGOg0Wjw7LPPoq2tDVu3bkVbW9uo12lqasIvf/lLVzfBmjVr8Pjjj/u7VKJxYzcBEdEYCIKAyMhImEwmTJ8+HQUFBVCpvL+FOp1OdHd3o6urC11dXaiursbFixfR0dERoKqJxoZhgIhoHIxGI55//nk8/fTT0Gq147ruiRMn8E//9E8oLS31U3VEd4dhgIhoHARBgFqtRnx8PFatWoVvfOMbY76uKIqw2+04f/48Dh48yE2OKGgwDBAR3YWkpCQ8/fTTmD9//riv+8UXX+C9997DrVu3gmKxp6/X4O7HE06ZDB0cQEhEdA8mT56M559/HkVFRbh8+fKYrzcwMIA//elPiIqKAgBkZ2djxYoVo45D8IeLFy/i3Llzbi+7devWiLUV1Go1Vq9ejdzcXERGRgaiRPIzhgEiGhOtVjvuPnIlSEtLQ1paGsxmM65du+Y6PtriTXa7HWfPnnX9/sADD2Dx4sVQq9V+q9WTmzdv4vDhw2M+X61WY9asWSgsLPRjVRRIDANENKrIyEhs2rQJGRkZCAsLk7qcoLR06VLX+AGr1Yq33nprTNMPh5SXlw+bhhhIra2tAb9PCi4MA0Q0Ko1Gg4kTJyI1NVXqUoJWcnIykpOTAdxZ2lmn043r+j09Pbh+/bo/SvOpyMhIGI1GthKFGIYBIiIaszVr1uChhx5CTEyM1KWQDzEMEBEAICIiAgUFBbDb7SMuMxqN7B4YB7Vajby8PBiNRreXNzY2oru7O8BV3Z2IiAhkZGS4ui8yMzORmJgocVXka4LIzcuJCHdWyxscHHQ7lUwQBGi1WklGusuRKIoYGBhw+1iKoojf/va3KCoqkqCy8ZsxYwZeeukl18BGrVYrySBH8i+2DBARAEClUo27n5vcEwTB42MpiiKmT5/u2rzIarWiuLg46LaODg8PxwMPPICJEydCr9czAIQ4tgwQEQXY1992Gxoa8PLLLwddt0Fqaiq2bdvmGhvABYZCG1sGiIgC7OsfrNHR0Vi3bh36+/slrGikyMhIGAwGhgCFYMsAERGRwnE0EBERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKRzDABERkcIxDBARESkcwwAREZHCMQwQEREpHMMAERGRwjEMEBERKdz/A1afkIOMPbtGAAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5678\n"
     ]
    }
   ],
   "source": [
    "#展示图片\n",
    "import matplotlib.pyplot as plt\n",
    "img = Image.open('./data/5678.png')\n",
    "# 显示图像\n",
    "plt.imshow(img)\n",
    "plt.axis('off')  # 可选，关闭坐标轴\n",
    "plt.show()\n",
    "\n",
    "predict_digit = []\n",
    "\n",
    "for image in digit_images:\n",
    "    predict_digit.append(predict_image(image, model))\n",
    "print(''.join(predict_digit))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aed09c19-5b63-48f8-955f-5f64a706e736",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
